/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Presentation;

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JComponent;
import javax.swing.JTextField;

/**
 *
 * @author Domenico
 */
class InputVerifierCF extends InputVerifierNotEmpty{
     public InputVerifierCF(String nomeCampo) {
        super(nomeCampo);
    }

    @Override
    public boolean verify(JComponent input) {
        JTextField jt = (JTextField) input;
        String codice = jt.getText().toUpperCase();
       
        if ((codice.length() == 16) && 
             controlloNomeCognome(codice) &&
             controlloData(codice) && 
             controlloCitta(codice) &&
             controlloCodiceFinale(codice)) {
            return true;
        }
  
        notificaErrore("Inserire: ", "Dato non inserito o non corretto", input);
  
        return false;
    }

    private boolean controlloNomeCognome(String codice) {
        String nomeCognome = codice.substring(0, 6);
        return isString(nomeCognome);
    }
    private boolean isString(String stringa) {
        Pattern pattern = Pattern.compile("[A-Z]+");
        Matcher matcher = pattern.matcher(stringa);
        return matcher.find();
    }
    private boolean isNumeric(String stringa) {
        Pattern pattern = Pattern.compile("[0-9]+");
        Matcher matcher = pattern.matcher(stringa);
        return matcher.find();
    }
    private boolean controlloData(String input) {
        String stringa = input.substring(6, 11);
        boolean valida = false;
        if (stringa.length() != 5) {
           return false;
        }
        Pattern pattern = Pattern.compile("[0-9][0-9][ABCDEHLMPRST][0-9][0-9]");
        Matcher matcher = pattern.matcher(stringa);
        valida = matcher.find();
        if (valida) {
            pattern = Pattern.compile("[0-9][0-9][ACELMRT][0-9][0-9]");
            matcher = pattern.matcher(stringa);
            valida = matcher.find();
            int giorni = Integer.parseInt(stringa.substring(3));
            if (valida && giorni <= 71 && giorni > 0) {
                return true;
            }
            pattern = Pattern.compile("[0-9][0-9][DHPS][0-9][0-9]");
            matcher = pattern.matcher(stringa);
            valida = matcher.find();
            giorni = Integer.parseInt(stringa.substring(3));
            if (valida && giorni <= 70 && giorni > 0) {
                return true;
            }
            pattern = Pattern.compile("[0-9][0-9][B][0-9][0-9]");
            matcher = pattern.matcher(stringa);
            valida = matcher.find();
            giorni = Integer.parseInt(stringa.substring(3));
            if (valida && giorni <= 68 && giorni > 0) {
                return true;
            } else {
                if (valida && giorni == 69 && giorni > 0 && isBisestile(Integer.parseInt(stringa.substring(1, 2)))) {
                    return true;
                } else {
                    valida = false;
                }
            }
        } else {
            pattern = Pattern.compile("[ABCDEHLMPRST]");
            matcher = pattern.matcher(stringa.substring(2, 2));
            valida = matcher.find();
            if (valida && (isNotNumericAfterIndex(7, input) ||
                    isNotNumericAfterIndex(8, input)) ||
                    isNotNumericAfterIndex(9, input) ||
                    isNotNumericAfterIndex(11, input) ||
                    isNotNumericAfterIndex(12, input)) {
                return true;
            } else {
                return false;
            }
                
        }
        return valida;
    }
    private boolean isNotNumericAfterIndex(int index, String stringa) {
        String testo = stringa.substring(index);
        Pattern pattern = Pattern.compile("[A-Z]+");
        Matcher matcher = pattern.matcher(testo);
        return matcher.find();
    }
    private boolean isBisestile(int anno) {
        return (anno % 4 == 0);
    }

    private boolean controlloCitta(String input) {
        String stringa = input.substring(11, 15);
        if (stringa.length() != 4) {
            return false;
        }
        Pattern pattern = Pattern.compile("[A-Z][0-9][0-9][0-9]");
        Matcher matcher = pattern.matcher(stringa);
        boolean valida = matcher.find();
        if (!valida && isString(stringa.substring(0,1))) {
            if (isNotNumericAfterIndex(1, stringa) ||
                isNotNumericAfterIndex(2, stringa) ||
                isNotNumericAfterIndex(3, stringa)) {
                return true;
            } else {
                return false;
            }
        }
        
        return valida;
    }

    private boolean controlloCodiceFinale(String input) {
        HashMap<String, Integer> valoriDispari = new HashMap<String, Integer>();
        valoriDispari.put("0", new Integer(1));
        valoriDispari.put("1", new Integer(0));
        valoriDispari.put("2", new Integer(5));
        valoriDispari.put("3", new Integer(7));
        valoriDispari.put("4", new Integer(9));
        valoriDispari.put("5", new Integer(13));
        valoriDispari.put("6", new Integer(15));
        valoriDispari.put("7", new Integer(17));
        valoriDispari.put("8", new Integer(19));
        valoriDispari.put("9", new Integer(21));
        valoriDispari.put("A", new Integer(1));
        valoriDispari.put("B", new Integer(0));
        valoriDispari.put("C", new Integer(5));
        valoriDispari.put("D", new Integer(7));
        valoriDispari.put("E", new Integer(9));
        valoriDispari.put("F", new Integer(13));
        valoriDispari.put("G", new Integer(15));
        valoriDispari.put("H", new Integer(17));
        valoriDispari.put("I", new Integer(19));
        valoriDispari.put("J", new Integer(21));
        valoriDispari.put("K", new Integer(2));
        valoriDispari.put("L", new Integer(4));
        valoriDispari.put("M", new Integer(18));
        valoriDispari.put("N", new Integer(20));
        valoriDispari.put("O", new Integer(11));
        valoriDispari.put("P", new Integer(3));
        valoriDispari.put("Q", new Integer(6));
        valoriDispari.put("R", new Integer(8));
        valoriDispari.put("S", new Integer(12));
        valoriDispari.put("T", new Integer(14));
        valoriDispari.put("U", new Integer(16));
        valoriDispari.put("V", new Integer(10));
        valoriDispari.put("W", new Integer(22));
        valoriDispari.put("X", new Integer(25));
        valoriDispari.put("Y", new Integer(24));
        valoriDispari.put("Z", new Integer(23));
        
        HashMap<String, Integer> valoriPari = new HashMap<String, Integer>();
        valoriPari.put("0", new Integer(0));
        valoriPari.put("1", new Integer(1));
        valoriPari.put("2", new Integer(2));
        valoriPari.put("3", new Integer(3));
        valoriPari.put("4", new Integer(4));
        valoriPari.put("5", new Integer(5));
        valoriPari.put("6", new Integer(6));
        valoriPari.put("7", new Integer(7));
        valoriPari.put("8", new Integer(8));
        valoriPari.put("9", new Integer(9));
        valoriPari.put("A", new Integer(0));
        valoriPari.put("B", new Integer(1));
        valoriPari.put("C", new Integer(2));
        valoriPari.put("D", new Integer(3));
        valoriPari.put("E", new Integer(4));
        valoriPari.put("F", new Integer(5));
        valoriPari.put("G", new Integer(6));
        valoriPari.put("H", new Integer(7));
        valoriPari.put("I", new Integer(8));
        valoriPari.put("J", new Integer(9));
        valoriPari.put("K", new Integer(10));
        valoriPari.put("L", new Integer(11));
        valoriPari.put("M", new Integer(12));
        valoriPari.put("N", new Integer(13));
        valoriPari.put("O", new Integer(14));
        valoriPari.put("P", new Integer(15));
        valoriPari.put("Q", new Integer(16));
        valoriPari.put("R", new Integer(17));
        valoriPari.put("S", new Integer(18));
        valoriPari.put("T", new Integer(19));
        valoriPari.put("U", new Integer(20));
        valoriPari.put("V", new Integer(21));
        valoriPari.put("W", new Integer(22));
        valoriPari.put("X", new Integer(23));
        valoriPari.put("Y", new Integer(24));
        valoriPari.put("Z", new Integer(25));
        
        HashMap<Integer, String> valoriResto = new HashMap<Integer, String>();
        valoriResto.put(new Integer(0), "A");
        valoriResto.put(new Integer(1), "B");
        valoriResto.put(new Integer(2), "C");
        valoriResto.put(new Integer(3), "D");
        valoriResto.put(new Integer(4), "E");
        valoriResto.put(new Integer(5), "F");
        valoriResto.put(new Integer(6), "G");
        valoriResto.put(new Integer(7), "H");
        valoriResto.put(new Integer(8), "I");
        valoriResto.put(new Integer(9), "J");
        valoriResto.put(new Integer(10), "K");
        valoriResto.put(new Integer(11), "L");
        valoriResto.put(new Integer(12), "M");
        valoriResto.put(new Integer(13), "N");
        valoriResto.put(new Integer(14), "O");
        valoriResto.put(new Integer(15), "P");
        valoriResto.put(new Integer(16), "Q");
        valoriResto.put(new Integer(17), "R");
        valoriResto.put(new Integer(18), "S");
        valoriResto.put(new Integer(19), "T");
        valoriResto.put(new Integer(20), "U");
        valoriResto.put(new Integer(21), "V");
        valoriResto.put(new Integer(22), "W");
        valoriResto.put(new Integer(23), "X");
        valoriResto.put(new Integer(24), "Y");
        valoriResto.put(new Integer(25), "Z");
        
        //Somma Dispari
        int sommaDispari = 0;
        for (int i = 0; i < input.length() - 1; i = i + 2) {
            sommaDispari = sommaDispari + valoriDispari.get(input.substring(i, i + 1));
        }
        int sommaPari = 0;
        for (int i = 1; i < input.length() - 1; i = i + 2) {
            sommaPari = sommaPari + valoriPari.get(input.substring(i, i + 1));
        }
        int resto = (sommaDispari + sommaPari) % 26;
        if (valoriResto.get(new Integer (resto)).equals(input.substring(15))) {
            return true;
        }
        return false;
    }
}
